/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simulador;

import Ventana.VentanaV34;
import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.LinkedList;
import javax.swing.JFrame;

/**
 *
 * @author Fede
 */
public class SimuladorMaq1V2 {
    
    private GeneradorLlegadasCheques glc;
    
    private LinkedList listaCheque;//colaDeLlegadaDeCheques
    private LinkedList colaCheques;//colaDeChequesASerProcesados
    private LinkedList listaInterace;
    
    
    private double reloj=0;
    private double proximaLlegada=0;
    private boolean estadoMaquina;//false=libre, true=ocupado
    private double proximoFinProceso=0;
    
    private int cantidadChequeProcesados=0;
    private double tiempoMaximoDeEspera=0;
    private double tiempoEsperaAcumulado=0;
    
    private double costoPorEspera=0;
    
    private boolean primeraVuelta=true;
    
    private VentanaV34 ventana;
    
    private float capacidadProcesamiento;
    private float costoEspera;
    private float vidaUtil;
    
    private Cheque chequeActual;
    private Cheque chequeSig;
    
    private Cheque chequeProcesandose;
    
    
    public SimuladorMaq1V2(LinkedList listaCheques, VentanaV34 ven,int capacidadProcesamiento, int costoEspera, int vidaUtil)
     {
         this.glc = new GeneradorLlegadasCheques();
         
         this.listaCheque= listaCheques;
         this.listaInterace= new LinkedList();
         this.colaCheques= new LinkedList();
         
         this.ventana=ven;
         
         this.capacidadProcesamiento= (float)3600/capacidadProcesamiento;//2,25
         this.costoEspera = costoEspera/(float)3600;
         this.vidaUtil = vidaUtil*3600;
       
     }
     
//      private double tiempoEntreLlegadas(double random)
//    {
//        double tiempo=-4.5*Math.log(1-random);
//        return this.redondearADosDecimales(tiempo);
//        
//    }
//      
//    private double redondearADosDecimales(double rnd)
//    {
//        DecimalFormat twoDForm = new DecimalFormat("#.###");
//         return Double.valueOf(twoDForm.format(rnd).replace(',','.'));
//    }  
     
    
            
     public LinkedList simularProcesador()
     {
         
         Cheque C1 = this.glc.generarLlegadaCheque();
         
         this.listaCheque.add(C1);
         
         Iterator iterActual= this.listaCheque.iterator();
         Iterator iterSig =this.listaCheque.iterator();
         
         this.chequeActual= (Cheque)iterSig.next();
         
         this.setInterface(-1,"Inicio",this.reloj,chequeActual.getRandomLlegada(),chequeActual.getTiempoEntreLlegada(),chequeActual.getTiempoLLegada(),this.colaCheques.size(),"Libre",this.proximoFinProceso,this.cantidadChequeProcesados,chequeActual.getTiempoEspera());
         
         this.proximaLlegada= chequeActual.getTiempoLLegada();
         this.proximoFinProceso=100000000;
         double tiempoEspera=chequeActual.getTiempoEspera();
         
         
         while(this.reloj<=this.vidaUtil)
         {
             //System.out.println("Reloj: "+this.reloj+"- Vida Util: "+this.vidaUtil);
             
             if(this.proximaLlegada<this.proximoFinProceso)
             {
                 this.reloj=this.proximaLlegada;
                 
                 if(primeraVuelta){
                     this.proximoFinProceso=0;
                     this.primeraVuelta=false;
                 }
                 else
                 {
                     chequeActual=this.chequeSig;
                     this.listaCheque.add(chequeActual);
                 }
                 
                 chequeSig=this.glc.generarLlegadaCheque();
                 this.listaCheque.add(chequeSig);
                 
                 
                 
                 if(this.estadoMaquina==false)//maquina desocupada?
                 {
                     //inicia proceso de cheque
                     this.chequeProcesandose=chequeActual;
                     
                     if(iterSig.hasNext())
                     {
                         chequeSig = (Cheque)iterSig.next();
                         this.proximaLlegada = chequeSig.getTiempoLLegada();
                     }
                     
                     //this.proximoFinProceso= reloj + 0.44;
                     this.proximoFinProceso= reloj + this.capacidadProcesamiento;
                     
                     String cad="";
                     if(this.estadoMaquina)
                     {
                         cad="Libre";
                         this.estadoMaquina=false;
                     }
                     else
                     {
                         cad="Ocupado";
                         this.estadoMaquina=true;
                     }
                           
                     
                     this.setInterface(1,
                             "LLegada Cheque "+chequeActual.getNumero(),//
                             this.reloj,//
                             chequeSig.getRandomLlegada(),
                             chequeSig.getTiempoEntreLlegada(),
                             this.proximaLlegada ,
                             this.colaCheques.size(),
                             cad,
                             this.proximoFinProceso,
                             this.cantidadChequeProcesados,
                             0);
                     
                     
                 }
                 else
                 { //problema
                     //se suma el cheque a la cola de cheques
                     
                     this.colaCheques.add(chequeActual);
                     
                     if(iterSig.hasNext())
                     {
                         chequeSig = (Cheque)iterSig.next();
                         this.proximaLlegada = chequeSig.getTiempoLLegada();
                     }
                     
                     this.setInterface(1,
                             "LLegada Cheque "+chequeActual.getNumero(),//
                             this.reloj,//
                             chequeSig.getRandomLlegada(),
                             chequeSig.getTiempoEntreLlegada(),
                             this.proximaLlegada ,
                             this.colaCheques.size(),
                             "Ocupado",
                             this.proximoFinProceso,
                             this.cantidadChequeProcesados,
                             0);
                 }
             }
             else
             {//Fin proceso de cheque
                 
                 if(this.colaCheques.size()>0)
                 {//hay cheques en cola
                     
                     //inicia proceso de cheque
                     
                     this.reloj=this.proximoFinProceso;//
                     
                     int nroChequeProcesandose=this.chequeProcesandose.getNumero();
                     
                     Iterator iterColaCheque = this.colaCheques.iterator();
                         
                     chequeProcesandose= (Cheque)iterColaCheque.next();
                     iterColaCheque.remove();
                     
                     tiempoEspera = this.reloj-chequeProcesandose.getTiempoLLegada();
                     chequeProcesandose.setTiempoEspera(tiempoEspera);
                     
                     if(tiempoEspera>this.tiempoMaximoDeEspera)
                     {
                         this.tiempoMaximoDeEspera=tiempoEspera;
                     }
                     
                     this.tiempoEsperaAcumulado=this.tiempoEsperaAcumulado+tiempoEspera;
                     
                     this.cantidadChequeProcesados++;
                     
                      //this.proximoFinProceso= reloj + 0.44;
                     this.proximoFinProceso= reloj + this.capacidadProcesamiento;
                      
                     //iterColaCheques.remove();
                      
                      this.setInterface(1,
                             "Fin Procesamiento Cheque"+nroChequeProcesandose,//
                             this.reloj,//
                             chequeSig.getRandomLlegada(),
                             chequeSig.getTiempoEntreLlegada(),
                             this.proximaLlegada ,
                             this.colaCheques.size(),
                             "Ocuapdo",
                             this.proximoFinProceso,
                             this.cantidadChequeProcesados,
                             tiempoEspera);
                 
                 }
                 else
                 {
                     //inicia proceso de cheque
                     
                     this.reloj=this.proximoFinProceso;
                     this.proximoFinProceso=100000000;
                     
                     String cad="";
                     if(this.estadoMaquina){
                         cad="Libre";
                         this.estadoMaquina=false;
                     }
                     else{
                         cad="Ocupado";
                         this.estadoMaquina=true;
                     }
                     
                     this.cantidadChequeProcesados++;
                     
                     this.setInterface(1,
                             "Fin Procesamiento Cheque"+this.chequeProcesandose.getNumero(),//
                             this.reloj,//
                             chequeSig.getRandomLlegada(),
                             chequeSig.getTiempoEntreLlegada(),
                             this.proximaLlegada ,
                             this.colaCheques.size(),
                             cad,
                             this.proximoFinProceso,
                             this.cantidadChequeProcesados,
                             0);
                 }
             }
         }
         
         //System.out.println(this.tiempoEsperaAcumulado);
         this.costoPorEspera=this.tiempoEsperaAcumulado*0.167;
         this.cargarDatos();
         
         
         return this.listaInterace;
     }
     
     private void cargarDatos()
     {
         this.ventana.getTxtCantidadChequesProcesados1().setText(""+this.cantidadChequeProcesados);
         this.ventana.getTxtTiempoMaximoEspera1().setText(""+this.tiempoMaximoDeEspera);
         this.ventana.getTxtCostoChequeEnEspera1().setText(""+this.costoPorEspera);
         
     }
     
     private void setInterface(int maquina,String evento,double reloj,double RNDLlegadaCheque, double tiempoEntreLlegada, double proximaLlegada,
             int colaCheque, String estado, double finAtencionMaquina, int cantidadChequesProcesados, double tiempoDeEspera)
     {
         Interface inter = new Interface();
         
         inter.setMaquina(maquina);
         inter.setEvento(evento);
         inter.setReloj(reloj);
         inter.setRNDLlegadaCheque(RNDLlegadaCheque);
         inter.setTiempoEntreLLegada(tiempoEntreLlegada);
         inter.setProximaLlegada(proximaLlegada);
         inter.setColaCheques(colaCheque);
         inter.setEstadoMaquina(estado);
         inter.setFinAtencionMaquina(finAtencionMaquina);
         inter.setCantidadChequesProcesados(cantidadChequesProcesados);
         inter.setTiempoDeEsperaCheques(tiempoDeEspera);
         
         this.listaInterace.add(inter);
         
        // System.out.println(evento);
     }
     
//     public void mostrar()
//     {
//         String cad="";
//         Iterator iter= this.listaInterace.iterator();
//         
//         while(iter.hasNext())
//         {
//             Interface i=(Interface)iter.next();
//             cad=cad+i.toString()+"\n";
//             
//         }
//         System.out.println("Evento    |     Reloj     |    RND    |    Tiempo Entre Llegada    |     Proxima Llegada: ");
//         System.out.println(cad);
//         
//     }
     
    
}


